import { defineConfig } from 'vite'
import fs from 'fs'
import path from 'path'

export default defineConfig({
  server: {
    // ========== 主机配置 ==========

    /**
     * host - 指定服务器应该监听哪个 IP 地址
     * 默认: 'localhost' - 只能本地访问
     * 设置为 '0.0.0.0' 或 true 会监听所有地址，包括局域网和公网IP
     * 设置为 IP 字符串可指定特定网络接口
     */
    host: 'localhost',
    // host: '0.0.0.0',  // 允许局域网访问
    // host: '192.168.1.100',  // 指定特定IP

    // ========== 允许的主机 ==========

    /**
     * allowedHosts - 允许访问开发服务器的主机名列表
     * 用于防止 DNS 重绑定攻击
     * 设置为 true 允许所有主机
     */
    allowedHosts: [
      'localhost',
      '127.0.0.1',
      'mysite.local',
      '.example.com'  // 允许所有子域名
    ],
    // allowedHosts: true,  // 允许所有主机（不安全）

    // ========== 端口配置 ==========

    /**
     * port - 指定开发服务器端口
     * 默认: 5173
     * 设置为 0 时，会随机选择可用端口
     */
    port: 5173,
    // port: 3000,
    // port: 0,  // 随机端口

    /**
     * strictPort - 端口严格模式
     * 设置为 true 时，如果端口被占用则直接退出
     * 设置为 false 时，会尝试下一个可用端口
     */
    strictPort: false,
    // strictPort: true,  // 端口被占用时直接报错

    // ========== HTTPS 配置 ==========

    /**
     * https - 启用 TLS + HTTP/2
     * 设置为 true 使用自签名证书
     * 提供证书对象使用自定义证书
     */
    https: false,
    // https: true,  // 使用自签名证书
    // https: {
    //   // 自定义证书
    //   key: fs.readFileSync(path.resolve(__dirname, 'localhost-key.pem')),
    //   cert: fs.readFileSync(path.resolve(__dirname, 'localhost.pem')),
    //   // 或者使用 pfx 文件
    //   // pfx: fs.readFileSync(path.resolve(__dirname, 'certificate.pfx')),
    //   // pfxPassword: 'password'
    // },

    // ========== 自动打开浏览器 ==========

    /**
     * open - 启动时自动在浏览器中打开应用程序
     * 布尔值、URL 路径字符串或浏览器名称
     */
    open: false,
    // open: true,  // 打开默认URL
    // open: '/about',  // 打开特定路径
    // open: {
    //   app: {
    //     name: 'google chrome',  // 指定浏览器
    //     arguments: ['--incognito']  // 无痕模式
    //   }
    // },

    // ========== 代理配置 ==========

    /**
     * proxy - 开发服务器代理规则
     * 用于解决跨域问题，将 API 请求代理到后端服务器
     */
    proxy: {
      // 简单字符串代理
      '/api': 'http://localhost:3001',

      // 详细配置
      '/api/v2': {
        target: 'http://localhost:3002',
        changeOrigin: true,  // 修改请求头中的 Origin
        rewrite: (path) => path.replace(/^\/api\/v2/, '/api'),  // 路径重写
        configure: (proxy, options) => {
          // 代理实例配置
          proxy.on('error', (err, req, res) => {
            console.log('proxy error', err)
          })
        }
      },

      // WebSocket 代理
      '/socket.io': {
        target: 'ws://localhost:3003',
        ws: true,  // 代理 WebSocket
        changeOrigin: true
      },

      // 多个路径代理到同一目标
      '^/users/.*': {
        target: 'http://localhost:3004',
        changeOrigin: true
      },

      // 绕过代理函数
      '/bypass': {
        target: 'http://localhost:3005',
        bypass: (req, res, options) => {
          // 返回 null 使用代理，返回 false 返回 404
          if (req.headers.accept?.includes('html')) {
            return '/index.html'  // 跳过代理
          }
        }
      }
    },

    // ========== CORS 配置 ==========

    /**
     * cors - 配置 CORS (跨源资源共享)
     * 布尔值或详细配置对象
     */
    cors: true,
    // cors: false,  // 禁用 CORS
    // cors: {
    //   // 详细配置
    //   origin: 'http://localhost:3000',  // 允许的源
    //   methods: ['GET', 'POST', 'PUT', 'DELETE'],  // 允许的方法
    //   allowedHeaders: ['Content-Type', 'Authorization'],  // 允许的请求头
    //   exposedHeaders: ['X-Custom-Header'],  // 暴露的响应头
    //   credentials: true,  // 允许发送 Cookie
    //   maxAge: 86400  // 预检请求缓存时间
    // },

    // ========== 自定义响应头 ==========

    /**
     * headers - 为所有响应设置自定义头
     */
    headers: {
      'X-Custom-Header': 'vite-dev-server',
      'X-Content-Type-Options': 'nosniff',
      'X-Frame-Options': 'DENY',
      // 安全头
      'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
      'X-XSS-Protection': '1; mode=block'
    },

    // ========== HMR (热模块替换) 配置 ==========

    /**
     * hmr - 配置热模块替换
     */
    hmr: {
      // 禁用 HMR
      // enabled: false,

      // HMR 连接协议
      protocol: 'ws',  // 'ws' | 'wss'

      // HMR 服务器主机
      host: 'localhost',

      // HMR 服务器端口
      port: 24678,

      // HMR 连接路径
      path: '/__vite_hmr',

      // HMR 连接超时时间
      timeout: 30000,

      // 服务器错误时是否回退到完整重载
      overlay: true,  // 在浏览器中显示错误覆盖层

      // 网络连接失败时重试次数
      retry: 3,

      // 服务器完全失联时的行为
      // 'page-reload' | 'fail'
      serverShutdown: 'page-reload'
    },

    // ========== 预热配置 ==========

    /**
     * warmup - 启动服务器时预先转换某些模块
     * 提高首次访问的响应速度
     */
    warmup: {
      // 预转换客户端入口文件
      clientFiles: [
        './src/main.js',
        './src/main.ts',
        './src/App.vue',
        './src/App.jsx'
      ],

      // 预转换 SSR 入口文件
      ssrFiles: [
        './src/entry-server.js'
      ]
    },

    // ========== 文件监听配置 ==========

    /**
     * watch - 监听文件系统配置
     */
    watch: {
      // 监听时忽略的文件
      ignored: [
        '**/node_modules/**',
        '**/dist/**',
        '**/.git/**',
        '**/test-results/**',  // 测试结果
        '**/coverage/**',      // 覆盖率报告
        '**/logs/**',          // 日志文件
        '**/temp/**'           // 临时文件
      ],

      // 使用轮询而非系统监听器（用于 Docker、网络文件系统等）
      usePolling: false,

      // 轮询间隔（毫秒）
      interval: 100,

      // 在 Windows 上忽略权限错误
      ignorePermissionErrors: false,

      // 原子写入检测（编辑器如 Vim 使用）
      atomic: true,

      // 总是跳过文件系统事件
      // alwaysStat: false,

      // 深度监听目录
      // depth: 99,

      // 监听器数量限制
      // awaitWriteFinish: false
    },

    // ========== 中间件模式 ==========

    /**
     * middlewareMode - 中间件模式
     * 将 Vite 服务器作为中间件使用，不启动自己的 HTTP 服务器
     */
    middlewareMode: false,
    // middlewareMode: true,  // 作为中间件使用
    // middlewareMode: 'html',  // 仅提供 HTML 的中间件模式

    // ========== 文件系统限制 ==========

    /**
     * fs - 文件系统服务限制
     * 防止服务意外暴露文件系统
     */
    fs: {
      /**
       * strict - 严格模式
       * 设置为 true 时，只允许在 `fs.allow` 中的文件被服务
       */
      strict: true,

      /**
       * allow - 允许服务的文件列表
       * 默认包含项目根目录
       */
      allow: [
        // 项目根目录
        process.cwd(),
        // 其他允许的目录
        '/path/to/allowed/dir',
        // monorepo 支持
        '/path/to/monorepo/packages'
      ],

      /**
       * deny - 拒绝服务的文件列表
       * 优先级高于 allow
       */
      deny: [
        '.env',          // 环境变量文件
        '.env.local',
        '.env.*.local',
        '*.{pem,crt,key}',  // 证书文件
        '**/secret/**',     // 秘密目录
        '**/node_modules/.cache/**'  // 缓存目录
      ]
    },

    // ========== 源 Origin 配置 ==========

    /**
     * origin - 定义开发调试阶段的生成资源的 URL origin
     * 用于确保资源使用正确的 origin
     */
    origin: '__vite_origin__',
    // origin: 'http://localhost:5173',
    // origin: 'https://dev.example.com',

    // ========== Sourcemap 忽略列表 ==========

    /**
     * sourcemapIgnoreList - 控制 sourcemap 中是否包含某些源
     * 函数返回 true 表示忽略该源
     */
    sourcemapIgnoreList: (sourcePath, sourcemapPath) => {
      // 忽略 node_modules 中的源
      if (sourcePath.includes('node_modules')) {
        return true
      }

      // 忽略特定路径
      if (sourcePath.includes('secret-module')) {
        return true
      }

      // 根据 sourcemap 路径判断
      if (sourcemapPath.includes('vendor')) {
        return true
      }

      return false
    }
    // sourcemapIgnoreList: false,  // 禁用忽略列表
  }
})